#include "allincludes.h"

//Don't forget about these static OneLine::variables....
	float OneLine::overlapCoefficient[MAXBINSNUM];
	int OneLine::overlapEndIndex;
	float OneLine::afterpulse[MAXBINSNUM];
	int OneLine::afterpulseEndIndex;
	float OneLine::betaM[MAXBINSNUM]; //BetaM=Molecule Back Scatter Coefficient
	float OneLine::integratedBetaM[MAXBINSNUM]; //for faster calculation
	float OneLine::TProfile[MAXBINSNUM];
	float OneLine::PProfile[MAXBINSNUM];
	LidarINI OneLine::ini;
	int OneLine::staticBinsLengthX;
	int OneLine::USEABLESTARTINDEX;
	int OneLine::FIRSTDATAINDEX;
	float OneLine::SINALPHA;
	float OneLine::COSALPHA;

OneLine::OneLine(void)
{
	binsLengthX=1;
	bIsSigma=false;
	bIsNormalized=false;
	averageTime=0;
	maxIndexOfSigmaedData=-1;

}
OneLine::OneLine(const OneLine &oldLine)
{
	binsNum=oldLine.binsNum;
	headSize=oldLine.headSize;
	averageTime=oldLine.averageTime;
	binsLengthX=oldLine.binsLengthX;
	bIsSigma=oldLine.bIsSigma;
	bIsNormalized=oldLine.bIsNormalized;
	maxIndexOfSigmaedData=oldLine.maxIndexOfSigmaedData;
	//remember to add other aux vars here
	
	
	memcpy(&iSoftwareVersion, &oldLine.iSoftwareVersion, HEADSIZE);
	memcpy(analogData, oldLine.analogData, MAXANALOGNUM*sizeof(float));
	memcpy(data, oldLine.data, MAXBINSNUM*sizeof(float));
}

OneLine OneLine::operator = (OneLine oldLine)
{
	binsNum=oldLine.binsNum;
	headSize=oldLine.headSize;
	averageTime=oldLine.averageTime;
	binsLengthX=oldLine.binsLengthX;
	bIsSigma=oldLine.bIsSigma;
	bIsNormalized=oldLine.bIsNormalized;
	maxIndexOfSigmaedData=oldLine.maxIndexOfSigmaedData;
	//remember to add other aux vars here
	
	
	memcpy(&iSoftwareVersion, &oldLine.iSoftwareVersion, HEADSIZE);
	memcpy(analogData, oldLine.analogData, MAXANALOGNUM*sizeof(float));
	memcpy(data, oldLine.data, MAXBINSNUM*sizeof(float));

	return *this;
}
OneLine OneLine::operator +(OneLine oldLine)
{
	OneLine temp(*this);
	if(binsLengthX!=oldLine.binsLengthX)
	{
		cout<<"Can't do adding between two data with different resolution !"<<endl;
		exit(FAILED);
	}
	if((bIsNormalized!=oldLine.bIsNormalized)||(bIsSigma!=oldLine.bIsSigma))
	{
		cout<<"Can't do adding between two data with different stage... e.g. normalized vs unnormalized."<<endl;
		exit(FAILED);
	}

	else
	{
		for(int i=0;i<binsNum;i++)
		{
			temp.data[i]+=oldLine.data[i];
		}
		for(int i=0;i<iNumberOfAnalog;i++)
		{
			temp.analogData[i]+=oldLine.analogData[i];
		}
		temp.averageTime+=oldLine.averageTime;
		temp.lNumberOfShotsPerAverage+=oldLine.lNumberOfShotsPerAverage;
		return temp; 
	}
	return *this;  //Notice, this doesn't work actually, 
}

OneLine OneLine::operator /(int div)
{
	if(div==0)
	{
		cout<<"Error: Deviding 0!"<<endl;
		exit(0);
	}
	else
	{
		OneLine temp(*this);
	
		for(int i=0;i<binsNum;i++)
		{
			temp.data[i]/=div;
		}
		for(int i=0;i<iNumberOfAnalog;i++)
		{
			temp.analogData[i]/=div;
		} 
		return temp; //this is what actually being returned...
	}
	return *this; //but the pgCC always warns about no return at the end
}

//OneLine OneLine::GetOverlapCurve()
//{
//	//Haven't Do Nb and Nap correction yet~~
//	OneLine newLine;
//
//	for(int i=1;i< 2000 ;i++)
//	{
//		//Background Correction
//		float afterNb=this->data[i]-this->analogData[5];
//		//to avoid log(-x.x)
//		if (afterNb<0.00000000001)
//			afterNb=0.00000000001;
//		newLine.data[i]=log(afterNb*pow((7.5*i),2));
//	//	cout<<newLine.data[i]<<"  ";
//	}
//
//	return newLine;
//}
string OneLine::GetAverageMinString()
{
	stringstream ss;
	ss<<GetAverageMinInt();
	string averageMinStr;
	ss>>averageMinStr;
	return averageMinStr;
}

float OneLine::IndexToHeight(int index)
{
	//int FIRSTDATAINDEX;
	//if(binsLengthX==1) FIRSTDATAINDEX=FIRSTDATAINDEX_7_5M;
	//else if(binsLengthX==2) FIRSTDATAINDEX=FIRSTDATAINDEX_15M;
	//else {cout<<"Can't handle this resolution!"<<endl;exit(FAILED);}
	return 0.0075*binsLengthX*(0.5+index-FIRSTDATAINDEX)*SINALPHA;
}
float OneLine::IndexToDistance(int index)
{
	/*int FIRSTDATAINDEX;
	if(binsLengthX==1) FIRSTDATAINDEX=FIRSTDATAINDEX_7_5M;
	else if(binsLengthX==2) FIRSTDATAINDEX=FIRSTDATAINDEX_15M;
	else {cout<<"Can't handle this resolution!"<<endl;exit(FAILED);}*/
	return 0.0075*binsLengthX*(0.5+index-FIRSTDATAINDEX);
}
int OneLine::HeightToIndex(float height)
{
	/*int FIRSTDATAINDEX;
	if(binsLengthX==1) FIRSTDATAINDEX=FIRSTDATAINDEX_7_5M;
	else if(binsLengthX==2) FIRSTDATAINDEX=FIRSTDATAINDEX_15M;
	else {cout<<"Can't handle this resolution!"<<endl;exit(FAILED);}*/
	return (int)(height/SINALPHA/0.0075/binsLengthX)+FIRSTDATAINDEX;
}
int OneLine::DistanceToIndex(float distance)
{
	/*int FIRSTDATAINDEX;
	if(binsLengthX==1) FIRSTDATAINDEX=FIRSTDATAINDEX_7_5M;
	else if(binsLengthX==2) FIRSTDATAINDEX=FIRSTDATAINDEX_15M;
	else {cout<<"Can't handle this resolution!"<<endl;exit(FAILED);}*/
	return (int)(distance/0.0075/binsLengthX)+FIRSTDATAINDEX;
}
///////////////

